const express = require("express");
const multer = require("multer");
const fs = require("fs");
const bodyParser = require("body-parser");
const path = require("path");
const cors = require("cors");
const app = express();
const uploadDir = path.join(__dirname, "uploads"); // 上传目录
const DefualtChunkSize = 2 * 1024 * 1024;
// 确保上传目录存在
if (!fs.existsSync(uploadDir)) {
        fs.mkdirSync(uploadDir);
        fs.chmodSync(uploadDir, 0o777)
}

app.use(cors()); // 允许跨域请求
app.use(bodyParser.json({ limit: '2048mb', extended: true }));
app.use(express.json()); // 解析 JSON 请求体

// 检查已上传的分片
app.post("/check", (req, res) => {
        const { fileHash } = req.body;
        console.log("fileHash check", fileHash)

        const fileChunkDir = path.join(uploadDir, fileHash); // 分片存储目录
        if (!fs.existsSync(fileChunkDir)) {
                return res.json([]); // 如果目录不存在，返回空数组
        }

        const flieList = [];
        readFile(fileChunkDir, flieList)
        let dones = [];
        flieList.forEach(item => {
                if (item.size == DefualtChunkSize) {
                        dones.push(item.index)
                }
        });
        res.json(dones);

});


// 设置 multer 中间件，用于处理文件上传
const storage = multer.diskStorage({
        destination: (req, file, cb) => {
                const fileHash = req.query.fileHash; // 从查询参数获取 fileHash
                const chunkDir = path.join(uploadDir, fileHash);
                // 确保切片目录存在
                if (!fs.existsSync(chunkDir)) {
                        fs.mkdirSync(chunkDir, { recursive: true });
                }
                cb(null, chunkDir);
        },
        filename: (req, file, cb) => {
                const { chunkIndex } = req.query;
                cb(null, `chunk-${chunkIndex}`);
        },
});

const upload = multer({ storage: storage });

// 上传文件分片
app.post("/upload", upload.single("chunk"), (req, res) => {
        const { fileHash } = req.body;
        res.json({
                code: 200,
                msg: "上传成功"
        });
});


// 合并分片
app.post("/merge", (req, res) => {
        const { fileName, fileHash, totalChunks } = req.body;
        const fileChunkDir = path.join(uploadDir, fileHash);
        const filePath = path.join(uploadDir, fileName);

        // 创建可写流用于最终合并文件
        const writeStream = fs.createWriteStream(filePath);

        for (let i = 0; i < totalChunks; i++) {
                const chunkPath = path.join(fileChunkDir, `chunk-${i}`);
                const data = fs.readFileSync(chunkPath); // 读取分片
                writeStream.write(data); // 写入最终文件

        }

        writeStream.end(); // 关闭流
        fs.rmSync(fileChunkDir, { recursive: true, force: true });
        res.status(200).json({
                code: 200,
                msg: "合并成功",
                data: "/uploads/" + fileName
        })
});


function readFile(path, filesList) {
        files = fs.readdirSync(path);//需要用到同步读取 
        files.forEach(walk);
        function walk(file) {
                states = fs.statSync(path + '/' + file);
                //创建一个对象保存信息 
                var obj = new Object();
                obj.size = states.size;//文件大小，以字节为单位 
                obj.index = parseInt(file.split("-")[1]);//文件名 
                filesList.push(obj);

        }
}

app.listen(5000, () => {
        console.log("服务器已启动：http://localhost:5000");
});